前言
在jenkins CI/CD流水线中以自动打包并push镜像的方式运行了一段时间之后,docker registry中堆积的历史镜像数量极多,磁盘空间告急,为此,有必要定期做镜像的清理,并释放镜像占用的存储空间
清除原理
Docker registry提供有restful api进行镜像管理,参考官方文档:
https://docs.docker.com/registry/spec/api/
Docker存储使用的aufs文件系统分层存储结构,将容器文件以读写分层的形式存储在宿主机中.在registry容器中,存放镜像的分层数据在宿主机上的挂载路径为:/var/lib/docker/volumes/{container_id}/_data/docker/registry/v2/blobs
关于docker aufs的存储模式,这篇文章写得非常通俗易懂,可以参考:
https://www.cnblogs.com/sammyliu/p/5931383.html
一图简介上层镜像生成及删除过程中的分层文件处理原理:
如图中文字解释,仅仅是调用api删除镜像是不够的,在删除了镜像之后,镜像的非共享分层文件还是会存放在磁盘中继续占用存储空间,因此,需要在删除镜像之后,使用docker registry自带的GC工具来进行垃圾分层(即无绑定镜像的分层)数据清除.
镜像分析
在了解以上前提后,开始排查哪些registry repo的历史镜像较多(分层数量多)
1.从宿主机进入docker registry容器内部,使用registry GC分析命令查看分层情况:
registry garbage-collect --dry-run /etc/docker/registry/config.yml # --dry-run选项为layer层级分析,并不实际进行GC
2.可以便捷使用以下命令对分层数较多的镜像做一个排序:
1 | registry garbage-collect --dry-run /etc/docker/registry/config.yml >> res.txt |
可以看到,如上10个repo历史镜像数量大,需要清理
删除镜像
注意:
无论是delete方法调用restful接口,还是registry 自带工具的GC清理,都需要registry的配置文件中开启允许删除功能:
/etc/docker/registry/config.yml1
2
3storage:
delete:
enabled: true
由于数量较多,因此使用python多线程来调用registry restful api进行删除操作,脚本内容如下,可根据自己的场景修改registry url:
1 | import requests |
运行结果:
1 | 仓库tooltest 共删除了17个历史镜像 |
空间清理
回到docker registry容器内,直接运行GC命令,这次不再加 –dry-run选项
1 | registry garbage-collect /etc/docker/registry/config.yml |
查看磁盘,可以发现磁盘容量已经空闲出许多了,镜像清理及存储空间释放完成!